package demo4;

import java.io.*;
import java.net.*;
import java.nio.file.*;

public class HttpServer {
    private static final int PORT = 8000;
    private static final String WEB_ROOT = "D:\\Program Files\\Git_JavaEE_Code\\java-ee_-test_-code\\hd-internet\\src\\webroot";

    public static void main(String[] args) {
        // 打印配置的根目录，确认路径正确
        System.out.println("网页根目录（绝对路径）：" + WEB_ROOT);
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("HTTP服务器启动，监听端口：" + PORT);
            while (true) {
                Socket clientSocket = serverSocket.accept();
                new Thread(new RequestHandler(clientSocket)).start();
            }
        } catch (IOException e) {
            System.err.println("服务器异常：" + e.getMessage());
        }
    }

    static class RequestHandler implements Runnable {
        private final Socket clientSocket;

        public RequestHandler(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try (BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
                 OutputStream out = clientSocket.getOutputStream()) {

                String requestLine = in.readLine();
                if (requestLine == null) return;
                String[] parts = requestLine.split(" ");
                if (parts.length < 3) {
                    sendError(out, 400, "Bad Request");
                    return;
                }
                String method = parts[0];
                String path = parts[1];
                System.out.println("收到请求：" + method + " " + path);

                // 解析请求头（跳过）
                String header;
                while ((header = in.readLine()) != null && !header.isEmpty()) {}

                switch (method) {
                    case "GET":
                        handleGet(out, path);
                        break;
                    case "POST":
                        handlePost(out, in);
                        break;
                    case "HEAD":
                        handleHead(out, path);
                        break;
                    default:
                        sendError(out, 405, "Method Not Allowed");
                }

            } catch (IOException e) {
                System.err.println("请求处理异常：" + e.getMessage());
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        private void handleGet(OutputStream out, String path) throws IOException {
            // 根路径映射到index.html
            if (path.equals("/")) {
                path = "/index.html";
            }

            // 用绝对路径定位文件（WEB_ROOT是绝对路径，path是相对路径）
            File file = new File(WEB_ROOT, path);

            // 打印实际查找的文件路径，方便验证
            System.out.println("查找文件：" + file.getAbsolutePath());
            System.out.println("文件是否存在：" + file.exists());

            if (file.exists() && file.isFile()) {
                String header = "HTTP/1.1 200 OK\r\n" +
                        "Content-Type: " + getContentType(file.getName()) + "\r\n" +
                        "Content-Length: " + file.length() + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
                out.write(header.getBytes());
                Files.copy(file.toPath(), out);
                System.out.println("文件发送成功：" + file.getName());
            } else {
                sendError(out, 404, "Not Found");
                System.out.println("文件不存在：" + file.getAbsolutePath());
            }
        }

        // 其他方法（handlePost/handleHead/sendError/getContentType）保持不变
        private void handlePost(OutputStream out, BufferedReader in) throws IOException {
            StringBuilder postData = new StringBuilder();
            while (in.ready()) {
                postData.append((char) in.read());
            }
            String response = "HTTP/1.1 200 OK\r\n" +
                    "Content-Type: text/plain\r\n" +
                    "Content-Length: " + (postData.length() + 10) + "\r\n" +
                    "Connection: close\r\n" +
                    "\r\n" +
                    "收到POST数据：" + postData;
            out.write(response.getBytes());
        }

        private void handleHead(OutputStream out, String path) throws IOException {
            if (path.equals("/")) {
                path = "/index.html";
            }
            File file = new File(WEB_ROOT, path);
            if (file.exists() && file.isFile()) {
                String header = "HTTP/1.1 200 OK\r\n" +
                        "Content-Type: " + getContentType(file.getName()) + "\r\n" +
                        "Content-Length: " + file.length() + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
                out.write(header.getBytes());
            } else {
                sendError(out, 404, "Not Found");
            }
        }

        private void sendError(OutputStream out, int statusCode, String message) throws IOException {
            String response = "HTTP/1.1 " + statusCode + " " + message + "\r\n" +
                    "Content-Type: text/html\r\n" +
                    "Connection: close\r\n" +
                    "\r\n" +
                    "<h1>" + statusCode + " " + message + "</h1>";
            out.write(response.getBytes());
        }

        private String getContentType(String fileName) {
            if (fileName.endsWith(".html") || fileName.endsWith(".htm"))
                return "text/html";
            if (fileName.endsWith(".css"))
                return "text/css";
            if (fileName.endsWith(".js"))
                return "application/javascript";
            if (fileName.endsWith(".png"))
                return "image/png";
            return "text/plain";
        }
    }
}
/*(tcp.port == 8000) and (
    (tcp.flags.syn == 1 and tcp.flags.ack == 0) or
    (tcp.flags.syn == 1 and tcp.flags.ack == 1) or
    (tcp.flags.syn == 0 and tcp.flags.ack == 1 and tcp.len == 0)
)*/